/**
 *  DoubleItem.java : IceBird project
 *  1:13:07 
 */
package icebird.compiler.ncomp.vs;

import icebird.compiler.ncomp.X86Assembler;
import icebird.compiler.ncomp.X86Register.GPR;
import icebird.metadata.BasicType;

/**
 * @author Sergey Shulepoff[Knott]
 */
public final class DoubleItem extends DoubleWordItem {

	/**
	 * @param l
	 */
	public DoubleItem(Location l) {
		super(l);
	}

	/* (non-Javadoc)
	 * @see icebird.compiler.ncomp.vs.DoubleWordItem#cloneConstant()
	 */
	protected DoubleWordItem cloneConstant() {
		if (!getLocation().isConstant())
			throw new IllegalStateException();
		
		DoubleConstantLocation d = (DoubleConstantLocation) getLocation();
		return new DoubleItem(ConstLocation.createDConst(d.getValue()));
	}

	/* (non-Javadoc)
	 * @see icebird.compiler.ncomp.vs.DoubleWordItem#loadConstant(icebird.compiler.ncomp.X86Register.GPR, icebird.compiler.ncomp.X86Register.GPR)
	 */
	protected void loadConstant(GPR lsb, GPR msb) {
		if (!getLocation().isConstant())
			throw new IllegalStateException();
		
		double value = ((DoubleConstantLocation) getLocation()).getValue();
		
		final long lvalue = Double.doubleToLongBits(value);
		final int lsbv = (int) (lvalue & 0xFFFFFFFFL);
		final int msbv = (int) ((lvalue >>> 32) & 0xFFFFFFFFL);
		
		X86Assembler asm = X86Assembler.getAsm();
		
		asm.move_const(lsb, lsbv);
		asm.move_const(msb, msbv);
	}

	/* (non-Javadoc)
	 * @see icebird.compiler.ncomp.vs.DoubleWordItem#popFPU(icebird.compiler.ncomp.X86Register.GPR, int)
	 */
	protected void popFPU(GPR r, int disp) {
		X86Assembler asm = X86Assembler.getAsm();
		asm.fstp64(r, disp);
	}

	/* (non-Javadoc)
	 * @see icebird.compiler.ncomp.vs.DoubleWordItem#pushConstant()
	 */
	protected void pushConstant() {
		if (!getLocation().isConstant())
			throw new IllegalStateException();
		
		double value = ((DoubleConstantLocation) getLocation()).getValue();
		
		final long lvalue = Double.doubleToLongBits(value);
		final int lsbv = (int) (lvalue & 0xFFFFFFFFL);
		final int msbv = (int) ((lvalue >>> 32) & 0xFFFFFFFFL);
		
		X86Assembler asm = X86Assembler.getAsm();
		
		asm.push(msbv);
		asm.push(lsbv);
	}

	/* (non-Javadoc)
	 * @see icebird.compiler.ncomp.vs.DoubleWordItem#pushFPU(icebird.compiler.ncomp.X86Register.GPR, int)
	 */
	protected void pushFPU(GPR r, int disp) {
		X86Assembler asm = X86Assembler.getAsm();
		asm.fld64(r, disp);
	}

	/* (non-Javadoc)
	 * @see icebird.compiler.ncomp.vs.Item#getType()
	 */
	public BasicType getType() {
		return BasicType.Double;
	}

}
